#include "server.h"

// Creates a connecto to an IRC server.
Server::Server(ServerInfo info)
{
	this->info	= info;
	this->conn	= new Connection(info.address, info.port);
	this->users	= UserList();
	this->channels = ChannelList();
}

// Opens a connection to the server.
bool Server::connect()
{
	if (!this->conn->open())
	{
		return false;
	}

	this->send("NICK "+this->info.nick);
	this->send("USER "+this->info.nick+" \""+this->info.host+"\" \"\" "+this->info.nick);

	return true;
}

// Terminates the connection to the server.
void Server::disconnect()
{
	this->conn->close();
}

// Check if the server is connected.
bool Server::isConnected()
{
	return this->conn->isOpen();
}

// Sends a message to the server.
void Server::send(std::string message)
{
	this->conn->send(message);
}

// Receives a message from the server.
std::string Server::receive(int max_length)
{
	char *buffer = new char[max_length];

	this->conn->receive(max_length, buffer);

	return std::string(buffer);
}

// Returns the server information.
ServerInfo Server::getServerInfo()
{
	return this->info;
}

SOCKET Server::getConnection()
{
	return this->conn->getSocket();
}

Channel *Server::addChannel(std::string name)
{
	if (name.empty())
	{
		return NULL;
	}

	Channel *channel = new Channel(name);

	this->channels.insert(ChannelListItem(channel->getName(), channel));

	return channel;
}

void Server::addChannel(Channel *channel)
{
	if (channel != NULL)
	{
		this->channels.insert(ChannelListItem(channel->getName(), channel));
	}
}

void Server::removeChannel(std::string name)
{
	ChannelListIter it = this->channels.find(name);

	if (it != this->channels.end())
	{
		this->channels.erase(it);
	}
}

ChannelList Server::getChannelList()
{
	return this->channels;
}

bool Server::hasChannel(std::string name)
{
	ChannelListIter it = this->channels.find(name);

	if (it == this->channels.end())
	{
		return false;
	}

	return true;
}

Channel *Server::getChannel(std::string name)
{
	ChannelListIter it = this->channels.find(name);

	if (it == this->channels.end())
	{
		return NULL;
	}

	return it->second;
}

void Server::addUser(User *user)
{
	if (user->nick.empty())
	{
		return;
	}

	this->users.insert(UserListItem(user->nick, user));
}

User *Server::addUser(std::string name)
{
	User *user = new User();
	user->nick = name;

	this->users.insert(UserListItem(name, user));

	return user;
}

User *Server::getUser(std::string name)
{
	UserListIter usrIter;
	if ((usrIter = this->users.find(name)) == this->users.end())
	{
		return NULL;
	}

	return usrIter->second;
}

void Server::removeUser(std::string nick)
{
	UserListIter usrIter = this->users.find(nick);
	if (usrIter == this->users.end())
	{
		return;
	}

	this->users.erase(usrIter);
}

bool Server::hasUser(std::string nick)
{
	UserListIter iter = this->users.find(nick);
	if (iter == this->users.end())
	{
		return false;
	}

	return true;
}

UserList Server::getUserList()
{
	return this->users;
}

void Server::join(std::string name)
{
	if (name.substr(0, 1) != "#")
	{
		name = "#" + name;
	}

	this->send("JOIN " + name);
}

void Server::part(std::string name)
{
	if (name[0] != '#')
	{
		name = "#" + name;
	}

	this->send("PART " + name);
}